package com.dd.common.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dd.common.config.GlobalConfig;
import com.dd.common.entity.SysFile;
import com.dd.common.entity.SysFileFolder;
import com.dd.common.enums.ErrorEnum;
import com.dd.common.enums.FileTypeEnum;
import com.dd.common.exception.BusinessException;
import com.dd.common.mapper.SysFileFolderMapper;
import com.dd.common.plugin.storage.StorageDriver;
import com.dd.common.pojo.dto.FileUploadDTO;
import com.dd.common.pojo.vo.UploadFilesVo;
import com.dd.common.service.SysFileService;
import com.dd.common.mapper.SysFileMapper;
import com.dd.common.utils.RequestContextUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;

/**
* @author cheng
* @description 针对表【c_sys_file(文件上传记录表)】的数据库操作Service实现
* @createDate 2025-08-23 17:00:06
*/
@Service
public class SysFileServiceImpl extends ServiceImpl<SysFileMapper, SysFile>
    implements SysFileService{

    @Resource
    private SysFileFolderMapper sysFileFolderMapper;

    /**
     * 上传文件，支持hash校验实现秒传
     * @param file 文件
     * @param dto 上传参数
     * @return 文件信息
     */
    @Override
    public UploadFilesVo uploadFile(MultipartFile file, FileUploadDTO dto) {
        // 校验文件是否已经存在
        SysFile fileRecord = this.checkFile(dto.getHash());
        if (fileRecord != null) {
            // 添加新的文件记录
            SysFile sysFile = new SysFile();
            sysFile.setFolderId(dto.getDirId());
            sysFile.setHash(dto.getHash());
            sysFile.setBizId(dto.getBizId());
            sysFile.setFileSize(fileRecord.getFileSize());
            sysFile.setMimeType(fileRecord.getMimeType());
            sysFile.setType(fileRecord.getType());
            sysFile.setOriginalName(file.getOriginalFilename());
            sysFile.setFileName(fileRecord.getFileName());
            sysFile.setFilePath(fileRecord.getFilePath());
            sysFile.setUploadUserId(StpUtil.getLoginIdAsLong());
            this.save(sysFile);

            UploadFilesVo vo = new UploadFilesVo();
            vo.setName(file.getOriginalFilename());
            vo.setSize(fileRecord.getFileSize());
            vo.setExt(fileRecord.getFileName().substring(fileRecord.getFileName().lastIndexOf(".")));
            vo.setUrl(RequestContextUtils.uri() + GlobalConfig.contextPath + fileRecord.getFilePath());
            vo.setPath(fileRecord.getFilePath());
            return vo;
        }

        if (dto.getDirId() == null) {
            // 若未指定目录，则设置默认上传的目录为：临时目录 temp，目录不存在就创建
            SysFileFolder folder = sysFileFolderMapper.selectOne(
                    new LambdaQueryWrapper<>(SysFileFolder.class).eq(SysFileFolder::getFolderKey, "temp")
                            .eq(SysFileFolder::getParentId, 0));
            if (folder != null) {
                dto.setDirId(folder.getId());
            } else {
                SysFileFolder defaultFolder = new SysFileFolder();
                defaultFolder.setFolderName("临时文件");
                defaultFolder.setFolderKey("temp");
                sysFileFolderMapper.insert(defaultFolder);
            }
        } else {
            SysFileFolder folder = sysFileFolderMapper.selectById(dto.getDirId());
            if (folder == null) throw new BusinessException(ErrorEnum.DATA_NOT_FOUND, "文件夹不存在");
        }

        String originalFilename =  file.getOriginalFilename();
        String extension = null;
        String mimeType = file.getContentType();

        // 获取扩展名
        if (originalFilename != null && originalFilename.contains(".")) {
            extension = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
        }
        // 自动分类
        FileTypeEnum fileType = FileTypeEnum.resolve(extension, mimeType);

        // 磁盘存储
        StorageDriver storageDriver = new StorageDriver();
        UploadFilesVo vo = storageDriver.upload(file, fileType);

        // 写入数据库文件记录
        SysFile sysFile = new SysFile();
        String savedOriginalFilename = originalFilename;
        if (originalFilename != null && originalFilename.length() > 250) {
            savedOriginalFilename = originalFilename.substring(0, 200) + extension;
        }

        sysFile.setFolderId(dto.getDirId());
        sysFile.setHash(dto.getHash());
        sysFile.setBizId(dto.getBizId());
        sysFile.setFileSize(file.getSize());
        sysFile.setMimeType(mimeType);
        sysFile.setType(fileType.getCode());
        sysFile.setOriginalName(savedOriginalFilename);
        sysFile.setFileName(Paths.get(vo.getPath()).getFileName().toString());
        sysFile.setFilePath(vo.getPath());
        sysFile.setUploadUserId(StpUtil.getLoginIdAsLong());

        this.save(sysFile);
        return vo;
    }

    @Override
    public Boolean moveBatch(Long folderId, List<Long> ids) {
        // 文件夹存不出在
        SysFileFolder folder = sysFileFolderMapper.selectById(folderId);
        if (folder == null) throw new BusinessException(ErrorEnum.DATA_NOT_FOUND, "文件夹不存在");
        return this.update(new LambdaUpdateWrapper<SysFile>()
                .in(SysFile::getId, ids)
                .set(SysFile::getFolderId, folderId));
    }

    @Override
    public SysFile checkFile(String hash) {
        return this.getOne(new LambdaQueryWrapper<SysFile>().eq(hash != null, SysFile::getHash, hash), false);
    }
}




